﻿/********************************************************************************/
// <copyright file="AdminRepository.cs" company="Asia E-Business Solutions">
//     Copyright © 2012. All right reserved
// </copyright>
// <history>
//     <change who="Phuoc Le" date="24/12/2012 2:59:54 PM">Created</change>
// </history>
/********************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using JLL.China.Model.DTO;
using LINQ = JLL.China.Infrastructure.Repositories.LINQ2SQL;

namespace JLL.China.Infrastructure.Repositories.Admin
{
    public class AdminRepository : SQLRepositoryBase<Model.Admin, Guid>, IAdminRepository
    {

        public override IList<Model.Admin> FindAll()
        {
            var admin = DataContext.Admins.OrderBy(x => x.UserName).ToList();
            if (admin != null)
            {
                var allAdmins = new List<Model.Admin>();
                foreach (var a in admin)
                {
                    allAdmins.Add(AdminFactory.FromLINQObject(a));
                }
                return allAdmins;
            }
            else
            {
                return new List<Model.Admin>();
            }
        }

        public override Model.Admin FindBy(Guid key)
        {
            var admin = DataContext.Admins.SingleOrDefault(x => key.Equals(x.Admin_ID));
            if (admin != null)
                return AdminFactory.FromLINQObject(admin);
            else
                return null;
        }

        private void PersistModuleAccessRights(Model.Admin item, IList<Model.Module> modules)
        {
            foreach (var m in modules)
            {
                DataContext.ModuleAccessRights.InsertOnSubmit(new LINQ.ModuleAccessRight
                {
                    Permission = m.Permission,
                    ModuleFID = m.ID,
                    AdminFID = item.ID
                });
            }
        }

        protected override void PersistDeletedItem(Model.Admin item)
        {
            var admin = DataContext.Admins.SingleOrDefault(x => item.ID.Equals(x.Admin_ID));
            if (admin != null)
            {
                DataContext.ModuleAccessRights.DeleteAllOnSubmit(admin.ModuleAccessRights);
                DataContext.Admins.DeleteOnSubmit(admin);
            }
        }

        protected override void PersistNewItem(Model.Admin item)
        {
            var admin = AdminFactory.ToLINQObject(item);
            DataContext.Admins.InsertOnSubmit(admin);
            
            PersistModuleAccessRights(item, item.Modules);
        }

        protected override void PersistUpdatedItem(Model.Admin item)
        {
            var existAcc = DataContext.Admins.SingleOrDefault(x => x.Admin_ID.Equals(item.ID));
            if (existAcc != null)
            {
                var acc = item;
                existAcc.UserName = acc.UserName;
                existAcc.Password = acc.Password;
                existAcc.IsSupperAdmin = acc.IsSupperAdmin;
                existAcc.IsActive = acc.IsActive;
                existAcc.Role = acc.Role;
                existAcc.GroupFID = acc.Group.ID;
                DataContext.ModuleAccessRights.DeleteAllOnSubmit(existAcc.ModuleAccessRights);
                PersistModuleAccessRights(acc, acc.Modules);
            }
            else
            {
                throw new Exception("Account not found to update");
            }
        }

        public Model.Admin FindByUsername(string username)
        {
            var acc = DataContext.Admins.SingleOrDefault(x => username == x.UserName);
            if (acc != null)
            {
                return AdminFactory.FromLINQObject(acc);
            }
            else
            {
                return null;
            }
        }

        public IList<Model.Admin> Search(AdminSearchCriteria searchCriteria)
        {
            var items = from m in DataContext.Admins
                        select m;

            if (!searchCriteria.Descending)
            {
                switch (searchCriteria.OrderBy)
                {
                    case AdminSearchOrder.IsSupperAdmin:
                        items = items.OrderBy(x => x.IsSupperAdmin);
                        break;
                    case AdminSearchOrder.IsActive:
                        items = items.OrderBy(x => x.IsActive);
                        break;
                    default:
                        items = items.OrderBy(x => x.UserName);
                        break;
                }
            }
            else
            {
                switch (searchCriteria.OrderBy)
                {
                    case AdminSearchOrder.IsSupperAdmin:
                        items = items.OrderByDescending(x => x.IsSupperAdmin);
                        break;
                    case AdminSearchOrder.IsActive:
                        items = items.OrderByDescending(x => x.IsActive);
                        break;
                    default:
                        items = items.OrderByDescending(x => x.UserName);
                        break;
                }
            }
            var list = items.Skip(searchCriteria.PageIndex * searchCriteria.Count).Take(searchCriteria.Count).ToList();
            var result = new List<Model.Admin>();
            foreach (var n in list)
            {
                result.Add(AdminFactory.FromLINQObject(n));
            }
            return result;
        }

        public bool ValidateLogin(string username, string password)
        {
            return DataContext.Admins.Any(x => x.Password == password && x.UserName == username && x.IsActive);
        }

        public int CountAdmins(AdminSearchCriteria searchCriteria)
        {
            return DataContext.Admins.Count();
        }

        public IList<Model.Module> FindAllModules()
        {
            var items = from m in DataContext.Modules
                        orderby m.Name
                        select new Model.Module
                        {
                            ID = (int)m.Module_ID,
                            ModuleName = m.Name,
                            Slug = m.Slug,
                            Status = m.Status
                        };
            return items.ToList();
        }

        #region IAdminRepository Members


        public Model.Module FindModuleById(int key)
        {
            var module = DataContext.Modules.SingleOrDefault(x => key.Equals(x.Module_ID));
            if (module != null)
                return ModuleFactory.FromLINQObject(module);
            else
                return null;
        }

        #endregion
    }
}
